import { Injectable } from '@angular/core';

/**
 * @Service
 * PageScrollListenerService
 * 负责监听组件的滚动事件的通用函数工具集合
 * */
export interface ScrollIndexItem {
  id: string;
  name: string;
}

@Injectable({
  providedIn: 'root'
})
export class PageScrollListenerService {
  private scrollTimer: number | null = null;
  private container: HTMLElement | null = null;
  private indexList: ScrollIndexItem[] = [];
  private activeIdUpdate!: (id: string) => void;
  private boundHandleScroll: () => void;

  constructor() {
    this.boundHandleScroll = this.handleScroll.bind(this);
  }

  init(
    container: HTMLElement,
    indexList: ScrollIndexItem[],
    activeIdUpdate: (id: string) => void
  ): void {
    this.container = container;
    this.indexList = indexList;
    this.activeIdUpdate = activeIdUpdate;
    this.bindScrollEvent();
  }

  private bindScrollEvent(): void {
    this.unbindScrollEvent();
    this.container?.addEventListener('scroll', this.boundHandleScroll);
  }

  private unbindScrollEvent(): void {
    this.container?.removeEventListener('scroll', this.boundHandleScroll);
  }

  private handleScroll(): void {
    if (!this.container || !this.indexList.length) return;

    if (this.scrollTimer !== null) {
      clearTimeout(this.scrollTimer);
    }

    // @ts-ignore
    this.scrollTimer = setTimeout(() => {
      // @ts-ignore
      const scrollPos = this.container.scrollTop + this.container.clientHeight / 3;
      let activeId = this.indexList[0].id;
      let maxTop = -1;

      for (const item of this.indexList) {
        // @ts-ignore
        const el = this.container.querySelector(`#${CSS.escape(item.id)}`) as HTMLElement | null;
        if (!el) continue;
        const top = el.offsetTop;
        if (top <= scrollPos && top > maxTop) {
          maxTop = top;
          activeId = item.id;
        }
      }

      this.activeIdUpdate(activeId);
      this.scrollTimer = null;
    }, 100);
  }

  scrollToSection(targetId: string, offset: number = 60): void {
    if (!this.container) return;
    const el = this.container.querySelector(`#${CSS.escape(targetId)}`) as HTMLElement | null;
    if (el) {
      this.container.scrollTo({
        top: el.offsetTop - offset,
        behavior: 'smooth'
      });
    } else {
      console.warn(`Element with id "${targetId}" not found.`);
    }
  }

  destroy(): void {
    if (this.scrollTimer) {
      clearTimeout(this.scrollTimer);
      this.scrollTimer = null;
    }
    this.unbindScrollEvent();
    this.container = null;
  }
}
